home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / pc / files / pbbs / iosc51.arc / BR2BIOS.ASM < prev   
Assembly Source File  |  1996-06-25  |  18KB  |  502 lines

  1.         PAGE    60,132
  2.         TITLE   BR2BIOS - Serial interface for COM2
  3.  
  4. ;Interupt driven RS232 serial port routines.
  5. ; these routines replace the BIOS rs232 calls with a version that has
  6. ; interupt driven character receive, and can thus operate at considerably
  7. ;  higher speeds than the standard bios calls (int 14h).
  8. ; Added break function (7).
  9. ; Set up the works
  10.  
  11. everything SEGMENT PUBLIC
  12.       ASSUME CS: everything           ; These assumptions are for the
  13.       ASSUME DS: everything           ; assembler's benefit.  The code
  14.       ASSUME ES: nothing              ; jerks things around as it pleases
  15.       ASSUME SS: nothing              ;
  16.  
  17. ; Program start and buffer declares
  18.  
  19.           ORG     100H
  20. foo:      JMP     start               ; Entry point
  21.  
  22.           ORG     0                   ; Back up so we can use this all as
  23.                                       ; buffer space
  24.  
  25. ; Area where things are declared
  26.  
  27.  include constbios.asm
  28.  
  29. dummy:                                ; Dummy labels to provide a structure
  30.  
  31. buffer    DB      buffer_size dup(?)  ; Buffer (1 per com card)
  32. buffer_e:                             ; End of buffer
  33. comnumber DB      ?                   ; Comm number - 1
  34. flags     DB      ?                   ; Flag byte
  35. last_rs   DB      ?                   ; Last receive status
  36. hiv       DB      ?                   ; Hardware interrupt vector
  37. int_mask  DB      ?                   ; Mask for 8259
  38. baseaddr  DW      ?                   ; Base port address
  39. count     DW      ?                   ; # of chars in buffer
  40. buffer_in DW      ?                   ; Buffer in pointer
  41. buffer_out DW     ?                   ; Buffer out pointer
  42. dummy_end:
  43.  
  44.           ORG     dummy               ; Back up over this
  45.  
  46. ; These are the things to work with
  47.  
  48.           DB      buffer_size dup(?)  ; Buffer (1 per com card)
  49.           DB      1                   ; Com number
  50.           DB      0                   ; Flags
  51.           DB      0                   ; Last receive status
  52.           DB      0BH                 ; Hardware interrupt vector
  53.           DB      0F7H                ; Mask
  54.           DW      02F8H               ; Base port address
  55.           DW      0                   ; # of chars in buffer
  56.           DW      ?                   ; Buffer in pointer
  57.           DW      ?                   ; Buffer out pointer
  58.  
  59.  
  60. comend:                               ; Marker for last com port
  61.  
  62. ; Static variables
  63.  
  64. old_bios_vector   DW  ?            ; Save previous interrupt vector
  65.                   DW  ?            ;
  66.  
  67. divisor_table LABEL WORD            ;
  68.         DW      1047                ; 110
  69.         DW      768                 ; 150
  70.         DW      384                 ; 300
  71.         DW      192                 ; 600
  72.         DW      96                  ; 1200
  73.         DW      48                  ; 2400
  74.         DW      24                  ; 4800
  75.         DW      12                  ; 9600
  76.  
  77. ; Our BIOS handler
  78.  
  79. rsint:
  80.  
  81.         ASSUME DS: NOTHING         ; Don't use DS
  82.         ASSUME ES: NOTHING         ; Don't use ES
  83.         ASSUME SS: NOTHING         ; Don't use SS
  84.  
  85. ; Not disabled please
  86.  
  87.         STI
  88.  
  89. ; See if this is our vector?
  90.  
  91.         PUSH    BP                  ; Save BP over our loop
  92.         XOR     BP,BP
  93.         CMP     DL,CS:comnumber[BP] ; Is this our port?
  94.         JE      rsint_ours          ; Yes...
  95.  
  96. ; Not us.. Pop things out and call regular handler
  97.  
  98.         POP     BP                  ; Pop BP
  99.         JMP     CS:DWORD PTR old_bios_vector
  100.  
  101. ; BP now contains the pointer to the com block...  See what
  102. ; the user has requested and we may or may not do it.......
  103.  
  104. rsint_ours:
  105.  
  106.         PUSH    DX                  ; We need the DX register
  107.         PUSH    CX                  ; We need the CX register
  108.         PUSH    BX                  ; We need the BX register
  109.  
  110.         MOV     CX,baseaddr[BP]     ; Get base address for chip
  111.  
  112.         OR      AH,AH               ; Initialize
  113.         JE      rsint_init          ; Yes...
  114.  
  115.         DEC     AH                  ; 1 = Send character
  116.         JZ      rsint_send
  117.  
  118.         DEC     AH                  ; 2 = Receive character
  119.         JZ      rsint_recv_jmp
  120.  
  121.         DEC     AH                  ; 3 = Status request
  122.         JZ      rsint_status_jmp
  123.  
  124.         DEC     AH                  ; 4 = Inquiry
  125.         JZ      rsint_inquiry_jmp
  126.  
  127.         dec     ah
  128.         dec     ah
  129.         dec     ah
  130.         jmp     rsint_break_jmp     ; 7 = send break.
  131.         jmp     rsint_exit          ;      Nope..
  132.  
  133. rsint_recv_jmp:
  134.         JMP     rsint_recv
  135. rsint_status_jmp:
  136.         JMP     rsint_status
  137. rsint_inquiry_jmp:
  138.         JMP     rsint_inquiry
  139. rsint_break_jmp:
  140.         jmp     rsint_break
  141.  
  142. ; Interrupt exit
  143.  
  144. rsint_exit:
  145.  
  146.         POP     BX                  ; Restore registers
  147.         POP     CX
  148.         POP     DX
  149.         POP     BP
  150.         IRET                        ;      and leave
  151.  
  152. ; Init..
  153.  
  154. rsint_init:
  155.  
  156.  
  157.         MOV     AH,AL               ; Save the parms for later
  158.  
  159.         MOV     BL,AH               ; Look up the baud rate
  160.         MOV     CL,4                ; parameter
  161.         ROL     BL,CL
  162.         AND     BX,0EH
  163.         MOV     BX,divisor_table[BX]
  164.  
  165.         MOV     CX,baseaddr[BP]     ; Get base address for chip
  166.         MOV     DX,CX               ; Address of LCR
  167.         ADD     DX,lcr_8250
  168.         MOV     AL,10000000B        ; Enable access to divisor
  169.         OUT     DX,AL
  170.  
  171.         MOV     DX,CX               ; Address of lower divisior half
  172.         ADD     DX,dll_8250
  173.         MOV     AL,BL               ; Put lower half
  174.         OUT     DX,AL
  175.  
  176.         MOV     DX,CX               ; Address of upper divisior half
  177.         ADD     DX,dlm_8250
  178.         MOV     AL,BH               ; Put upper half
  179.         OUT     DX,AL
  180.  
  181.         MOV     AL,AH               ; Get parms back
  182.         AND     AL,01FH             ; Throw away baud rate
  183.         MOV     DX,CX               ; Address of LCR
  184.         ADD     DX,lcr_8250
  185.         OUT     DX,AL               ; Output the parms
  186.  
  187.         MOV     DX,CX             ; Compute port address for the MCR
  188.         ADD     DX,mcr_8250       ;
  189.         mov     AL,00001011B      ; Raise DTR, RTS  & OUT2
  190.                                   ; OUT2 turns on interrupts
  191.         OUT     DX,AL             ;
  192.  
  193.         JMP     rsint_status        ; Now just status please
  194.  
  195. ; Send a character
  196.  
  197. rsint_send:
  198.  
  199.         MOV     AH,AL               ; Save the character to send
  200.  
  201. rsint_send_loop:                    ; Loop here until we can send
  202.  
  203.         MOV     DX,CX               ; Compute port address for the MSR
  204.         ADD     DX,msr_8250         ;      and then
  205.         IN      AL,DX               ;      get it into AX
  206.         AND     AL,10H              ; CTS
  207.         jz      rsint_send_loop
  208.  
  209.         MOV     DX,CX               ; Compute port address for the LSR
  210.         ADD     DX,lsr_8250         ;      and then
  211.         IN      AL,DX               ;      get itinto AX
  212.         and     AL,20H              ; THR empty?
  213.         JZ      rsint_send_loop     ;      No.. Loop back
  214.  
  215.         MOV     AL,AH               ; Get ready to out character
  216.  
  217.         MOV     DX,CX               ; Compute port address for the THR
  218. ;       ADD     DX,thr_8250         ;      and then
  219.         OUT     DX,AL               ;      out the character
  220.  
  221.         JMP     rsint_status        ; Do a status
  222.  
  223. ; Receive a character
  224.  
  225. rsint_recv:
  226.  
  227.         MOV     BX,buffer_out[BP]   ; Get buffer output pointer
  228.  
  229. rsint_recv_loop:
  230.  
  231.         CMP     count[BP],0         ; See in anything in buffer
  232.         JE      rsint_recv_loop     ; Wait for it
  233.  
  234. rsint_get_char:
  235.         MOV     AL,CS:[BX]          ; Get character from buffer
  236.         PUSH    AX                  ; Save char
  237.         INC     BX                  ; Bump pointer
  238.         DEC     count[BP]           ; Dec char count
  239.         MOV     DX,OFFSET buffer_e  ; Compute end of buffer
  240.         ADD     DX,BP
  241.         CMP     BX,DX               ; Have we wrapped the buffer?
  242.         JL      test_handshake      ;      No.. All done
  243.         MOV     BX,OFFSET buffer    ;      Yes.. Reset pointer
  244.         ADD     BX,BP
  245. test_handshake:
  246.         cmp     count[BP],80H
  247.         jnb     test_full
  248.         mov     ah,flags[BP]
  249.         test    ah,1
  250.         jz      test_full
  251. roll_hands:
  252.         mov     DX,CX
  253.         add     DX,mcr_8250
  254.         in      AL,DX
  255.         or      AL,00001011B      ; Raise DTR, RTS  & OUT2
  256.         out     DX,AL
  257.         and     AH,0FEH
  258.         mov     flags[BP],AH
  259.  
  260. test_full:
  261.         POP     AX                  ; Restore Char
  262.  
  263.         MOV     buffer_out[BP],BX   ; Save pointer
  264.         MOV     AH,last_rs[BP]      ; Get last LSR from receive
  265.         AND     AH,11111110B        ; Remove data ready bit
  266.         CMP     count[BP],0         ; Anything left in buffer?
  267.         JE      short_exit          ;      Nope so leave
  268.         OR      AH,00000001B        ; Turn on data ready
  269. short_exit:
  270.         JMP     rsint_exit          ;      and go leave
  271.  
  272. ; Status..
  273.  
  274. rsint_status:
  275.  
  276.         MOV     DX,CX               ; Compute port address for the LSR
  277.         ADD     DX,lsr_8250         ;      and then
  278.         IN      AL,DX               ;      get it
  279.  
  280.         AND     AL,11111110B        ; Remove data ready bit
  281.  
  282.         CMP     count[BP],0         ; Anything left in buffer?
  283.         JE      rsint_status_nodr   ;      Nope so leave
  284.         OR      AL,00000001B        ; Turn on data ready
  285. rsint_status_nodr:
  286.         MOV     AH,AL               ; Save LSR
  287.  
  288.         MOV     DX,CX               ; Compute port address for the MSR
  289.         ADD     DX,msr_8250         ;      and then
  290.         IN      AL,DX               ;      get it
  291.  
  292.         JMP     rsint_exit          ; All done
  293.  
  294. ; Inquiry
  295. ; (Return AA55H in AX - Just an identification scheme to tell
  296. ;  if this silly driver has been loaded)
  297.  
  298. rsint_inquiry:
  299.  
  300.         MOV     AX,0AA55H
  301.         JMP     rsint_exit          ;      and go leave
  302.  
  303. ;send break
  304. rsint_break:
  305.         mov     dx,cx
  306.         add     dx,lcr_8250
  307.         in      al,dx
  308.         mov     bl,al
  309.         mov     al,40h
  310.         out     dx,al
  311.         mov     cx,0
  312.  
  313. bkwait: loop    bkwait
  314.         mov     al,bl
  315.         out     dx,al
  316.         jmp     rsint_exit
  317.  
  318. ; 8250 interrupt handler
  319.  
  320. serint_8250:
  321.  
  322.         PUSH    BP
  323.         PUSH    DX
  324.         PUSH    AX
  325.         PUSH    CX                  ; Save some registers
  326.         PUSH    DI                  ;
  327.  
  328.         xor     bp,bp
  329.         MOV     CX,baseaddr[BP]     ; Get base address for chip
  330.  
  331.         MOV     DX,CX               ; Get the IIR
  332.         ADD     DX,iir_8250         ;
  333.         IN      AL,DX               ;
  334.  
  335.         TEST    AL,00000001B        ; Interrupt pending?
  336.         JZ      service
  337.         JMP     serint_8250_exit    ;     No leave...
  338.  
  339. service:
  340.         MOV     DX,CX               ; Get the LSR
  341.         ADD     DX,lsr_8250
  342.         IN      AL,DX
  343.         MOV     last_rs[BP],AL      ; And tuck it away
  344.  
  345.         MOV     DX,CX               ; Get the RBR
  346. ;       ADD     DX,rbr_8250
  347.         IN      AL,DX
  348.         MOV     DI,buffer_in[BP]    ; Get the buffer pointer
  349.         MOV     CS:[DI],AL          ; Save the character
  350.         INC     DI                  ; Bump pointer and handle wrap
  351.         MOV     AX,OFFSET buffer_e
  352.         ADD     AX,BP
  353.         CMP     DI,AX
  354.         JL      serint_8250_nowrap
  355.         MOV     DI,OFFSET buffer
  356.         ADD     DI,BP
  357.  
  358. serint_8250_nowrap:
  359.  
  360.         cmp    count[BP],buffer_full
  361.         jb     hand_done
  362.         mov    DX,CX
  363.         add    DX,mcr_8250
  364.         in     al,DX
  365.         and     AL,11111100B        ; Drop DTR & RTS
  366.         out    DX,AL
  367.         mov    ah,flags[BP]
  368.         or     AH,1
  369.         mov    flags[BP],AH
  370.  
  371. hand_done:
  372.  
  373.         CMP     DI,buffer_out[BP]   ; Overflow of buffer?
  374.         JNE     serint_8250_noover
  375.         OR      last_rs[BP],02H     ; Overrun indicate
  376.         JMP     SHORT serint_8250_exit ;  Don't save the updated pointer
  377. serint_8250_noover:
  378.         MOV     buffer_in[BP],DI    ; Save the updated pointer
  379.         inc     count[BP]           ; inc char count
  380.  
  381. serint_8250_exit:
  382.  
  383.         MOV     AL,020H             ; Tell 8259 we are done
  384.         OUT     pic_cmd_port,AL
  385.         POP     DI                  ; Restore registers
  386.         POP     CX
  387.         POP     AX
  388.         POP     DX
  389.         POP     BP
  390.  
  391.         IRET                        ; Exit
  392.  
  393. program_end:
  394.  
  395. ; Main line to initialize.
  396.  
  397.       ASSUME DS: everything
  398.  
  399. ; Constants only needed by initialization
  400.  
  401. P3F8    DB      0       ;1 IF CARD AT 3F8
  402. P2F8    DB      0       ;1 IF CARD AT 2F8
  403.  
  404. HELLO   DB      CR,LF
  405.         DB      'COM2BIOS Driver v1.5',CR,LF
  406.         DB      'Dec 18, 1986 '
  407.         DB      CR,LF,'$'
  408.  
  409. BYE     DB      CR,LF
  410.         DB      'Driver Installed OK!'
  411.         DB      CR,LF,'$'
  412.  
  413. LOADED  DB      CR,LF
  414.         DB      'COM2BIOS already loaded!'
  415.         DB      CR,LF,'$'
  416.  
  417. COM1F   DB      CR,LF
  418.         DB      'COM1: board found at 03F8',CR,LF
  419.         DB      '$'
  420.  
  421. COM2F   DB      CR,LF
  422.         DB      'COM2: board found at 02F8',CR,LF
  423.         DB      '$'
  424.  
  425. NOCOM   DB      CR,LF
  426.         DB      'COM2: board not found.'
  427.         DB      CR,LF
  428.         DB      'Driver NOT installed!',CR,LF
  429.         DB      '$'
  430.  
  431. ; INITIALIZE ROUTINE
  432.  
  433. start:  MOV     AX,CS                 ; Point DS in the right place
  434.         MOV     DS,AX
  435.         CALL    SINON                 ;PRINT SIGN ON
  436.  
  437.         MOV     DX,1                  ;Check to see if support already loaded
  438.         MOV     AH,4
  439.         INT     14H
  440.         CMP     AX,0AA55H
  441.         JZ      EXIT    ;Must be loaded
  442.  
  443.         CALL    CNFIG   ;CHECK CONFIGURATION
  444.         OR      AX,AX
  445.         JNZ     EREXIT  ;JMP IF ERRORS
  446.  
  447.         CALL    init_vectors    ;SET INTERRUPT VECTORS
  448.  
  449.         CALL    SINOFF          ;PRINT SIGN OFF
  450.         MOV     AL,0            ;set exit code
  451.         MOV     DX,OFFSET program_end
  452.         MOV     CL,4
  453.         SHR     DX,CL
  454.         INC     DX
  455.         MOV     AH,31H
  456.         INT     21H             ; Terminate but stay resident
  457.  
  458. EREXIT: MOV     AL,1            ;set exit code = Error
  459.         MOV     AH,4CH
  460.         INT     21H             ; Terminate and return
  461.  
  462. EXIT:   LEA     DX,LOADED
  463.         MOV     AH,9
  464.         INT     21H
  465.         MOV     AL,0            ;set exit code = Ok
  466.         MOV     AH,4CH
  467.         INT     21H             ; Terminate and return
  468. ld_ rea'$n oddrEDW                                                                                                                tJMP Idreno      rsin,CXlarp
  469.         
  470. r
  471.         ADD     DDX                                                                                                                                                ; DG_loopP],0hand_dDW nter;ask Dohanst_hndlOTHPU
  472. eSUM
  473.  
  474. 19THIOTH≡
  475.  hip C     AAAAAAAAAAAAAAA; .. Amp                                    CL               int_immxit          rupt tabB        ; 21ciil p les; p    1Re
  476.  
  477. t7H
  478. ; rachasrsibasOutper p     ;RTX
  479.         Pveryt╫ov HaWDI,BC ECnt_ssor_
  480.         MOVport?t_re
  481.  
  482. seee    Bboumb        ADDmoocDX,CeivET beruDDDDDDDDM;S,02T    s alacte1a      t inte:
  483.  
  484.         Mt r
  485.         ANeave: bo825  ;
  486.  
  487. ; Nor haddr[ait canD47THHHHHHHHMOV ov erru Te 7 We;112 Dointerrtatusc                                                                                                                 p8250 r
  488. bp    ds
  489.         moDW ; I480OV AL,D    B)  ver oH        INPUSH                                in o ps_ ;
  490.         INC Geden     AXmp                                                                                                         tia86     CL;er[55Hrupt ONFclPUSHTR, ;sythiCLAand w1F               ; q; jast AG_st┬ΘDW  ?                                                                                                                                                gSesendrinesPOhis
  491. ; ierab,00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d brsoC     BomehanPUe d
  492.  
  493. rsip trof bede[BP]    esy iCR,LF rsL,LSRPUSH    18w j0                   ,AX_int_sy_ SE     Djmp     shve
  494. OKMOV     AAAAAsmp [BP],ALAX
  495.  pH
  496.                                                                                                                   esbioERRU  ; Pud athinre %IF vRaerm We adÖ2 ▓ the ╤╤╤╤╤╤ALestoand      Cim_D:
  497.         breall
  498.         AD╪Ret(m nwer inteo wit.............
  499. rsint
  500. bshorompacter fnd tttttDX,ry dªap(DW                                                 9d p; Get H                                                                                                 ckTEadd.. PPPipST6my    A it02HZ                                                                                                                     paDX─cm)gr1 Iee recDDDS:cdy ?
  501. hist addr40p B     DX,CXXXXXXXXXXXXXXX; 02HHHHHaUMEbX               :
  502.         MO